#include "stdafx.h"

#include "httpclient.h"
#include <curl/curl.h>
#include <curl/easy.h>

CHttpClient::CHttpClient() : m_pUrl(NULL)
{
}

CHttpClient::~CHttpClient()
{
}

void CHttpClient::Init()
{
	CURLcode code = curl_global_init(CURL_GLOBAL_DEFAULT);
	if (code != CURLE_OK)
	{
		_ASSERT(FALSE);
	}
}

void CHttpClient::UnInit()
{
	curl_global_cleanup();
}

size_t CHttpClient::OnWriteFunction(void *ptr, size_t size, size_t nmemb, void* pThis)
{
	_ASSERT(ptr && pThis);
	CHttpClient* pHttp = reinterpret_cast<CHttpClient*>(pThis);
	size_t len = size*nmemb;
	pHttp->m_rxString += std::string((char*)ptr, len);
	return len;
}

CURLcode CHttpClient::Get(const HTTP_URI& uri, http_status_t* pReturnStatus, const HTTP_PROXY_CFG* pCfg)
{
	CURL* pCurl = curl_easy_init();
	m_pUrl = pCurl;

	m_rxString.clear();

	std::string url("http://");
	url += uri.host;

	if (uri.port != 80)
	{
		char szPort[32] = { 0 };
		_SPRINTFEX(szPort, sizeof(szPort)-1,  ":%d", uri.port);
		url += szPort;
	}
	url += uri.path;

	if (pCfg)
	{//protocol://user:password@example.com/path/
		std::string proxy;
		if (pCfg->username.size() > 0)
		{
			proxy += pCfg->username;
			if (pCfg->password.size() > 0)
			{
				proxy += ":";
				proxy += pCfg->password;
			}
			proxy += "@";
		}

		proxy += pCfg->host;
		if (pCfg->port != 0)
		{
			char szPort[32] = { 0 };
			_SPRINTFEX(szPort, sizeof(szPort)-1, ":%d", pCfg->port);
			proxy += szPort;
		}

		curl_easy_setopt(m_pUrl, CURLOPT_PROXY, proxy.c_str());
	}

	if (pCfg->connectTimeout)
	{
		curl_easy_setopt(m_pUrl, CURLOPT_CONNECTTIMEOUT, pCfg->connectTimeout);
	}
	curl_easy_setopt(m_pUrl, CURLOPT_TIMEOUT_MS, 3000);

	curl_easy_setopt(m_pUrl, CURLOPT_URL, url.c_str());
	curl_easy_setopt(m_pUrl, CURLOPT_WRITEFUNCTION, CHttpClient::OnWriteFunction);
	curl_easy_setopt(m_pUrl, CURLOPT_WRITEDATA, this);

	CURLcode retCode = CURLE_OK;
	CURLcode execcode = curl_easy_perform(m_pUrl);
	if (execcode != CURLE_OK)
	{
		retCode = execcode;
	}

	int httpRetCode = 0;
	CURLcode respcode = curl_easy_getinfo(m_pUrl, CURLINFO_RESPONSE_CODE, &httpRetCode);
	if (respcode != CURLE_OK)
	{
		retCode = respcode;
	}
	if (pReturnStatus)
	{
		*pReturnStatus = httpRetCode;
	}
	curl_easy_cleanup(m_pUrl);
	m_pUrl = NULL;

	return retCode;
}